package com.xyz.rok.tools.service.impl;

import com.xyz.rok.tools.constant.Integral;
import com.xyz.rok.tools.constant.SystemCode;
import com.xyz.rok.tools.exception.UnionException;
import com.xyz.rok.tools.mapper.UnionMapper;
import com.xyz.rok.tools.mapper.UnionMemberMapper;
import com.xyz.rok.tools.mapper.UserMapper;
import com.xyz.rok.tools.mapper.UserUnionMapper;
import com.xyz.rok.tools.model.Union;
import com.xyz.rok.tools.model.User;
import com.xyz.rok.tools.model.UserUnion;
import com.xyz.rok.tools.model.request.UnionRequest;
import com.xyz.rok.tools.service.UnionService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

@Service
public class UnionServiceImpl implements UnionService {

    @Resource
    private UnionMapper unionMapper;
    @Resource
    private UserMapper userMapper;
    @Resource
    private UserUnionMapper userUnionMapper;
    @Resource
    private UnionMemberMapper unionMemberMapper;

    @Override
    public int deleteByPrimaryKey(Long id) {
        return unionMapper.deleteByPrimaryKey(id);
    }

    @Override
    public int insert(Union record) {
        return unionMapper.insert(record);
    }

    @Override
    public int insertSelective(Union record) {
        return unionMapper.insertSelective(record);
    }

    @Override
    public Union selectByPrimaryKey(Long id) {
        return unionMapper.selectByPrimaryKey(id);
    }

    @Override
    public int updateByPrimaryKeySelective(Union record) {
        return unionMapper.updateByPrimaryKeySelective(record);
    }

    @Override
    public int updateByPrimaryKey(Union record) {
        return unionMapper.updateByPrimaryKey(record);
    }

    @Override
    public List<Union> selectUnionByUserId(Long userId) {
        return unionMapper.selectUnionByUserId(userId);
    }

    @Override
    public int selectUnionCountByUserId(Long userId) {
        return unionMapper.selectUnionCountByUserId(userId);
    }

    @Override
    public List<Union> selectUnionByServerId(Integer serverId) {
        return unionMapper.selectUnionByServerId(serverId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void joinUnion(UnionRequest unionRequest) throws Exception {
        List<Union> unions = unionMapper.selectUnionByName(unionRequest.getUnionName());
        if (unions.isEmpty()) {
            throw new UnionException(SystemCode.UNION_JOIN_NOT_EXIST);
        } else {
            Union union = unions.get(0);
            if (union.getInvitationCode().equals(unionRequest.getInvitationCode())) {
                List<UserUnion> userUnions = userUnionMapper.selectByUserIdAndUnionId(unionRequest.getUserId(), union.getId());
                if (userUnions.isEmpty()) {
                    User u = userMapper.selectByPrimaryKey(unionRequest.getUserId());
                    if (u != null && u.getHeadImg() == null && u.getNickName() == null) {
                        User user = new User();
                        user.setId(unionRequest.getUserId());
                        user.setHeadImg(unionRequest.getHeadImg());
                        user.setNickName(unionRequest.getNickName());
                        user.setUpdateTime(new Date());
                        userMapper.updateByPrimaryKeySelective(user);
                        userMapper.updateIntegral(union.getUserId(), Integral.INVITE_USER);
                    }
                    UserUnion userUnion = new UserUnion();
                    userUnion.setUserId(unionRequest.getUserId());
                    userUnion.setUnionId(union.getId());
                    userUnionMapper.insert(userUnion);
                } else {
                    throw new UnionException(SystemCode.UNION_JOINED);
                }
            } else {
                throw new UnionException(SystemCode.UNION_JOIN_CODE_ERROR);
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createUnion(UnionRequest unionRequest) throws Exception {
        if (unionMapper.selectUnionByName(unionRequest.getUnionName()).isEmpty()) {
            Date now = new Date();
            Union union = new Union();
            BeanUtils.copyProperties(unionRequest, union);
            union.setName(unionRequest.getUnionName());
            union.setCreateTime(now);
            User u = userMapper.selectByPrimaryKey(unionRequest.getUserId());
            if (u != null && u.getHeadImg() == null && u.getNickName() == null) {
                User user = new User();
                user.setId(unionRequest.getUserId());
                user.setHeadImg(unionRequest.getHeadImg());
                user.setNickName(unionRequest.getNickName());
                user.setUpdateTime(new Date());
                user.setIntegral(Integral.CREATE);
                userMapper.updateNickNameHeadImgIntegral(user);
            }
            UserUnion userUnion = new UserUnion();
            userUnion.setUserId(unionRequest.getUserId());
            unionMapper.insertSelective(union);
            userUnion.setUnionId(union.getId());
            userUnionMapper.insert(userUnion);
        } else {
            throw new UnionException(SystemCode.UNION_CREATE_EXIST);
        }
    }

    @Override
    public int updateUnion(UnionRequest unionRequest) throws Exception {
        List<Union> unions = unionMapper.selectUnionByName(unionRequest.getUnionName());
        if (unions.isEmpty()) {
            Union union = new Union();
            union.setName(unionRequest.getUnionName());
            union.setId(unionRequest.getUnionId());
            union.setInvitationCode(unionRequest.getInvitationCode());
            union.setCoordinateX(unionRequest.getCoordinateX());
            union.setCoordinateY(unionRequest.getCoordinateY());
            union.setUpdateTime(new Date());
            unionMapper.updateByPrimaryKeySelective(union);
        } else {
            for (Union union : unions) {
                if (!union.getUserId().equals(unionRequest.getUserId()) && !union.getId().equals(unionRequest.getUnionId())) {
                    throw new UnionException(SystemCode.UNION_CREATE_EXIST);
                } else if (union.getUserId().equals(unionRequest.getUserId()) && union.getId().equals(unionRequest.getUnionId())) {
                    Union unionUpdate = new Union();
                    unionUpdate.setId(union.getId());
                    unionUpdate.setName(unionRequest.getUnionName());
                    unionUpdate.setInvitationCode(unionRequest.getInvitationCode());
                    unionUpdate.setCoordinateX(unionRequest.getCoordinateX());
                    unionUpdate.setCoordinateY(unionRequest.getCoordinateY());
                    unionUpdate.setUpdateTime(new Date());
                    unionMapper.updateByPrimaryKeySelective(unionUpdate);
                }
            }
        }
        return 0;
    }

    @Override
    public int quitUnion(UnionRequest unionRequest) throws Exception {
        return userUnionMapper.deleteByPrimaryKey(unionRequest.getUserId(), unionRequest.getUnionId());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteUnion(UnionRequest unionRequest) {
        Union union = unionMapper.selectByPrimaryKey(unionRequest.getUnionId());
        if (union != null && union.getUserId().equals(unionRequest.getUserId())) {
            unionMapper.deleteByPrimaryKey(unionRequest.getUnionId());
            userUnionMapper.deleteByUnionId(unionRequest.getUnionId());
            unionMemberMapper.deleteByUnionId(unionRequest.getUnionId());
        }
        return 0;
    }
}
